package com.loveprogrammer.model;

import com.loveprogrammer.engine.AttackResult;
import com.loveprogrammer.utils.ConsoleColors;
import com.loveprogrammer.engine.enums.MonsterQualityEnum;
import com.loveprogrammer.engine.enums.QualityEnum;
import com.loveprogrammer.factory.template.MapTemplate;
import com.loveprogrammer.factory.template.MonsterTemplate;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @version 1.0.0
 * @description:
 * @author: eric
 * @date: 2022-08-02 18:18
 **/
public class Monster extends Character {

    private MonsterTemplate template;

    // 品质
    private QualityEnum qualityEnum;

    // TODO
    private List<MapTemplate.Drop> dropList;

    // 读档的时候用
    public Monster(String name, int strength, int armature, int constitution, int magic, int technique, int speed,
                   AtomicInteger hp, int hpMax, int baseStrength, int baseArmature, int baseConstitution, int baseMagic,
                   int baseTechnique, int baseSpeed, int baseHp, int level, MonsterQualityEnum monsterQualityEnum,
                   Integer currentExp, Integer nextLevelNeedExp, int attackType, MonsterTemplate template,
                   QualityEnum qualityEnum, int poisonResistance,
                   int flameResistance, int thunderResistance,int iceResistance,int position) {
        super(template.getId(),name,strength,armature,constitution,magic,technique,speed,hp,hpMax,baseStrength,baseArmature,
                baseConstitution,baseMagic,baseTechnique,baseSpeed,baseHp,level,monsterQualityEnum,currentExp,
                nextLevelNeedExp,attackType,poisonResistance,flameResistance,thunderResistance,iceResistance,position);
        this.template = template;
        this.qualityEnum = qualityEnum;
    }

    public Monster(String name, int level, int strength, int armature, int constitution,
                   int magic, int technique ,int speed, int attackType,
                   MonsterQualityEnum monsterQualityEnum,QualityEnum qualityEnum,
                   MonsterTemplate monsterTemplate, int poisonResistance,
                   int flameResistance, int thunderResistance, int iceResistance,int position) {
        super(monsterTemplate.getId(),name, level, strength, armature, constitution,magic,technique,speed,attackType,poisonResistance,
                flameResistance,thunderResistance,iceResistance,position);
        this.monsterQualityEnum = monsterQualityEnum;
        if(monsterTemplate == null){
            monsterTemplate = new MonsterTemplate();
        }
        this.template = monsterTemplate;
        this.qualityEnum = qualityEnum;
    }

    public Monster(MonsterTemplate template,QualityEnum qualityEnum){
        super(template.getId(),template.getName(), 1, template.getStrength(), template.getArmature(),
                template.getConstitution(),template.getMagic(),template.getTechnique(),template.getSpeed(),
                template.getAttackType()
                ,template.getPoisonResistance(),
                template.getFlameResistance(),
                template.getThunderResistance(),
                template.getIceResistance(),template.getPosition());
        this.monsterQualityEnum = MonsterQualityEnum.getByLevel(template.getQuality());
        this.template = template;
        this.qualityEnum = qualityEnum;
    }

    @Override
    public void levelUp(int exp) {
        this.setLevel(this.level + 1);
//        // 检查技能升级情况
//        if(!this.getSkills().isEmpty()){
//            this.getSkills().forEach(e -> e.levelUp(this.getLevel()));
//        }
        // 属性增加
        this.setStrength((int) (this.strength + template.getLevelUpStrength() * qualityEnum.getRatio()));
        this.setTechnique((int) (this.technique + template.getLevelUpTechnique()* qualityEnum.getRatio()));
        this.setArmature((int) (this.armature + template.getLevelUpArmature()* qualityEnum.getRatio()));
        this.setConstitution((int) (this.constitution + template.getLevelUpConstitution()* qualityEnum.getRatio()));
        this.hp.addAndGet((int) (10 * template.getLevelUpConstitution() * qualityEnum.getRatio()));
        this.hpMax = this.hp.get();
        this.setMagic((int) (this.magic + template.getLevelUpMagic()* qualityEnum.getRatio()));
        this.setSpeed((int) (this.speed + template.getLevelUpSpeed()* qualityEnum.getRatio()));
        // 基础属性增加
        this.setBaseStrength((int) (this.getBaseStrength() + template.getLevelUpStrength()* qualityEnum.getRatio()));
        this.setBaseMagic((int) (this.getBaseMagic() + template.getLevelUpMagic()* qualityEnum.getRatio()));
        this.setBaseTechnique((int) (this.getBaseTechnique() + template.getLevelUpTechnique()* qualityEnum.getRatio()));
        this.setBaseArmature((int) (this.getBaseArmature() + template.getLevelUpArmature()* qualityEnum.getRatio()));
        this.setBaseConstitution((int) (this.getBaseConstitution() + template.getLevelUpConstitution()* qualityEnum.getRatio()));
        this.setBaseSpeed((int) (this.getBaseSpeed() + template.getLevelUpSpeed()* qualityEnum.getRatio()));
        // 计算下一级需要的经验值
        int needExp = this.setNextLevelNeedExp();
        if(exp > needExp){
            levelUp(exp);
        }
    }

    public Monster upLevel(int level){
        this.strength = (int) (level * template.getLevelUpStrength() * qualityEnum.getRatio() + template.getStrength());
        this.armature = (int) (level * template.getLevelUpArmature() * qualityEnum.getRatio() + template.getArmature());
        this.constitution = (int) (level * template.getLevelUpConstitution() * qualityEnum.getRatio() + template.getConstitution());
        this.magic = (int) (level * template.getLevelUpMagic() * qualityEnum.getRatio() + template.getMagic());
        this.technique = (int) (level * template.getLevelUpTechnique() * qualityEnum.getRatio() + template.getTechnique());
        this.speed = (int) (level * template.getLevelUpSpeed() * qualityEnum.getRatio() + template.getSpeed());
        this.hp.set(Optional.of(this.constitution * 10).orElse(0));
        this.hpMax = this.hp.get();
        return this;
    }

    public MonsterTemplate getTemplate() {
        return template;
    }

    //角色打印信息的重写
    public String toString() {
        return "**** 名称：" + this.name + " " +
                "级别" + this.level + " " +
                "天赋" + this.qualityEnum.getColor() + this.qualityEnum.getDesc() + ConsoleColors.RESET + " " +
                "品质" + this.monsterQualityEnum.getDesc() + " " +
                "血量：" + this.hp + " " +
                "护甲值: " + this.armature + " " +
                "力量:" + this.strength + " " +
                "法力:" + this.magic + " " +
                "技巧:" + this.technique + " " +
                "速度:" + this.speed + " " +
                "抗性[毒:" + this.getPoisonResistance() + " 火:" + this.getFlameResistance()
                + " 雷:" + this.getThunderResistance() + " 冰:" + this.getIceResistance() + "] " +
                "经验(" + this.currentExp + "/" + this.nextLevelNeedExp + ") ****";
    }

    public QualityEnum getQualityEnum() {
        return qualityEnum;
    }

    public void setQualityEnum(QualityEnum qualityEnum) {
        this.qualityEnum = qualityEnum;
    }

    public void setTemplate(MonsterTemplate template) {
        this.template = template;
    }

    public List<MapTemplate.Drop> getDropList() {
        return dropList;
    }

    public void setDropList(List<MapTemplate.Drop> dropList) {
        this.dropList = dropList;
    }

    public int score() {
        return strength + armature * 2 + constitution + magic + technique + speed / 2;
    }

    @Override
    public AttackResult attack(List<? extends Character> defence) {
        return simpleAttack(defence);
    }

    @Override
    public int getDeadExp() {
        return (int) (level * monsterQualityEnum.getCode() * monsterQualityEnum.getCode() * getTemplate().getExp());
    }
}
